﻿
/*******************************************************************
 * Module：ReflectionUtil.cs
 * Author：LYH
 * Created：2011-31-24 15:03:55
 * Description：反射操作相关类
 * *******************************************************************/
using System;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using System.Windows.Forms;

namespace HJ212_Common
{
    /// <summary>
    /// ReflectionUtil 的摘要说明。
    /// </summary>
    public sealed class ReflectionUtil
    {
        private ReflectionUtil()
        {
        }

        public static BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.Public |
            BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;

        /// <summary>
        /// 调用方法
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="methodName"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static object InvokeMethod(object obj, string methodName, object[] args)
        {
            object objReturn = null;
            Type type = obj.GetType();
            objReturn = type.InvokeMember(methodName, bf | BindingFlags.InvokeMethod, null, obj, args);
            return objReturn;
        }
        /// <summary>
        /// 设置字段值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public static void SetField(object obj, string name, object value)
        {
            FieldInfo fi = obj.GetType().GetField(name, bf);
            fi.SetValue(obj, value);
        }
        /// <summary>
        /// 获得字段值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static object GetField(object obj, string name)
        {
            FieldInfo fi = obj.GetType().GetField(name, bf);
            if (fi == null) return null;
            return fi.GetValue(obj);
        }
        /// <summary>
        /// 给对象指定的属性设置值
        /// </summary>
        /// <param name="obj">要赋值的对象</param>
        /// <param name="name">要赋值的属性名</param>
        /// <param name="value">值</param>
        public static void SetProperty(object obj, string name, object value)
        {
            try
            {
                if (string.IsNullOrEmpty(Convert.ToString(value)))
                {
                    value = null;
                }
                PropertyInfo fi = obj.GetType().GetProperty(name);
                if (fi != null)
                {
                    if (fi.PropertyType.Name == "Nullable`1")
                    {
                        string type = fi.PropertyType.GetProperties()[1].PropertyType.FullName;
                        switch (type)
                        {
                            case "System.Int32":
                                value = Convert.ToInt32(value);
                                break;
                            case "System.Decimal":
                                value = Convert.ToDecimal(value);
                                break;
                            case "System.DateTime":
                                value = Convert.ToDateTime(value);
                                break;
                            case "System.Double":
                                value = Convert.ToDouble(value);
                                break;

                        }
                    }
                    if (fi.PropertyType.Name == "String")
                    {
                        value = string.Format("{0}", value);
                        if (string.IsNullOrEmpty(value.ToString()))
                        {
                            fi.SetValue(obj, null, null);
                        }
                        else
                        {
                            fi.SetValue(obj, value, null);
                        }
                    }
                    fi.SetValue(obj, value, null);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("InnerException:" + ex.InnerException + "....Message:" + ex.Message);
                //throw;
            }
        }
        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static object GetProperty(object obj, string name)
        {
            try
            {
                if (obj == null) return null;
                PropertyInfo fi = obj.GetType().GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
                if (fi == null) return null;
                return fi.GetValue(obj, null);
            }
            catch (Exception ex)
            {
                MessageBox.Show("InnerException:" + ex.InnerException + "....Message:" + ex.Message);
                return null;
                //throw;
            }
        }




        public static void ConvertObject(object source, object dest)
        {
            //获取公共属性
            var properties = source.GetType().GetProperties();
            var destproperties = dest.GetType().GetProperties();
            //获取列信息
            foreach (var item in destproperties)
            {
                var t = from q in properties
                        where q.Name == item.Name
                        select q;
                item.SetValue(dest, t.First().GetValue(source, null), null);

            }
        }


        /// <summary>
        /// 通过反射的方式，比较两个对象的字段和属性的值是否相等
        /// </summary>
        /// <param name="actual">比较的对象一</param>
        /// <param name="expected">比较的对象二</param>
        /// <returns>如果字段和属性都相等，那么返回True，否则为False。</returns>
        public static bool AreObjectsEqual(object actual, object expected)
        {
            if (actual == null || expected == null)
            {
                return false;
            }

            Type t1 = actual.GetType();
            Type t2 = expected.GetType();

            PropertyInfo[] pi1 = t1.GetProperties();
            PropertyInfo[] pi2 = t2.GetProperties();

            for (int i = 0; i < pi1.Length; i++)
            {
                try
                {
                    PropertyInfo i1 = pi1[i];
                    PropertyInfo i2 = pi2[i];

                    if (!i1.GetValue(actual, null).Equals(null) && !i2.GetValue(expected, null).Equals(null))
                    {
                        if (!i1.GetValue(actual, null).Equals(i2.GetValue(expected, null)))
                        {
                            return false;
                        }
                    }
                }
                catch (Exception)
                {
                    //throw;
                    return false;
                }
            }

            FieldInfo[] fi1 = t1.GetFields();
            FieldInfo[] fi2 = t2.GetFields();

            for (int i = 0; i < fi1.Length; i++)
            {
                try
                {
                    FieldInfo i1 = fi1[i];
                    FieldInfo i2 = fi2[i];

                    if (!i1.GetValue(actual).Equals(null) && !i2.GetValue(expected).Equals(null))
                    {
                        if (!i1.GetValue(actual).Equals(i2.GetValue(expected)))
                        {
                            return false;
                        }
                    }
                }
                catch (Exception)
                {
                    //throw;
                    return false;
                }
            }

            return true;
        }

        /// <summary>
        /// 根据类型创建对象。
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static object CreateNewObject(Type type)
        {
            return Activator.CreateInstance(type);
        }

        /// <summary>
        /// 取得类型全称字符串。
        /// </summary>
        /// <param name="o">对象</param>
        /// <returns></returns>
        public static string GetType(object o)
        {
            return o.GetType().FullName;
        }

        /// <summary>
        /// 根据限定的构造函数创建对象。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T CreateNewObject<T>() where T : new()
        {
            return new T();
        }

        /// <summary>
        /// 取得字段名称集合。
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        //private static FieldInfo[] GetFields(Type type)
        //{
        //    Type type = obj.GetType();
        //    return type.GetFields();
        //}


        /// <summary>
        /// 判断字段名称是否存在。
        /// </summary>
        /// <param name="obj">对象类型</param>
        /// <param name="fieldName">字段名称</param>
        /// <returns>true：存在；false：不存在。</returns>
        public static bool IsExiestField(Type type, string fieldName)
        {
            PropertyInfo fi = type.GetProperty(fieldName, bf);
            if (fi != null)
            {
                return true;
            }

            return false;
        }
    }
}
